package com.gin.no_gay_alliance.fragment.base;

import android.os.Bundle;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.viewbinding.ViewBinding;
import androidx.viewpager2.widget.ViewPager2;

import com.gin.no_gay_alliance.activity.BaseBindingActivity;
import com.gin.no_gay_alliance.app.MyApplication;
import com.gin.no_gay_alliance.base.ViewBindProvider;
import com.gin.no_gay_alliance.utils.MenuUtils;
import com.gin.no_gay_alliance.utils.MyHandler;
import com.gin.no_gay_alliance.utils.ReflectUtils;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * ViewBinding模式下的基础Fragment
 *
 * @author : ginstone
 * @version : v1.0.0
 * @since : 2023/8/24 15:45
 **/
public abstract class BaseBindingFragment<T extends ViewBinding> extends Fragment implements ViewBindProvider<T>, MyHandler.Callback, View.OnClickListener, TabLayoutMediator.TabConfigurationStrategy {
    protected final String TAG = this.getClass().getSimpleName();
    protected T b;
    protected MyHandler handler;
    protected Toolbar toolbar;

    /**
     * onCreateView 的后续操作
     */
    protected abstract void onCreateView();

    /**
     * 提供布局文件中的Toolbar
     *
     * @return toolbar
     */
    @Nullable
    protected Toolbar initToolbar() {
        return null;
    }

    /**
     * 使用反射生成ViewBinding对象
     *
     * @param inflater  渲染器
     * @param container 容器(Fragment用)
     * @return ViewBinding
     */
    @Override
    public T createViewBinding(@NonNull LayoutInflater inflater, @Nullable ViewGroup container) {
        try {
            ParameterizedType parameterizedType = ReflectUtils.findParameterizedType(getClass());
            if (parameterizedType != null) {
                Type type = parameterizedType.getActualTypeArguments()[0];
                if (type instanceof Class<?>) {
                    Class<?> clazz = ((Class<?>) type);
                    Method method = clazz.getMethod("inflate", LayoutInflater.class, ViewGroup.class, boolean.class);
                    return (T) method.invoke(clazz, inflater, container, false);
                } else {
                    System.out.println("type = " + type);
                }
            }
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            e.printStackTrace();
            return null;
        }
        return null;
    }

    /**
     * 处理消息
     *
     * @param message 消息
     * @return 是否消耗
     */
    @Override
    public boolean handleMessage(@NonNull Message message) {
        // 自己处理不了, 且有父级handler 发送消息给父级处理
        MyHandler parentHandler = getParentHandler();
        Log.d(this.getClass().getSimpleName(), "向父级抛出消息: " + message.what);
        Message msg = getParentHandler().obtainMessage(message.what, message.arg1, message.arg2, message.obj);
        parentHandler.sendMessage(msg);
        return false;
    }

    /**
     * 获取和处理参数
     *
     * @param arguments 参数
     */
    protected void handleArguments(Bundle arguments) {

    }

    /**
     * 点击事件统一处理
     *
     * @param v 被点击的View
     */
    @Override
    public void onClick(View v) {

    }

    /**
     * 配置 TabLayout
     *
     * @param tab      标签
     * @param position 位置
     */
    @Override
    public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {

    }

    /**
     * 关联TabLayout 和 ViewPager2
     *
     * @param tabLayoutMediator tabLayoutMediator
     * @param tabLayout         tabLayout
     * @param vp2               ViewPager2
     * @return TabLayoutMediator
     */
    protected final TabLayoutMediator attachTabLayout(TabLayoutMediator tabLayoutMediator, TabLayout tabLayout, ViewPager2 vp2) {
        // 如果已存在
        if (tabLayoutMediator != null) {
            //取消关联
            tabLayoutMediator.detach();
        }
        // 如果不存在，使用后续参数执行关联
        tabLayoutMediator = new TabLayoutMediator(tabLayout, vp2, this);
        tabLayoutMediator.attach();
        return tabLayoutMediator;
    }

    @Override
    public final View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        handleArguments(getArguments());
        b = createViewBinding(inflater, container);
        // 初始化handler
        handler = new MyHandler(requireContext(), this);
        // 开启从fragment中加载菜单
        setHasOptionsMenu(true);
        // 装载toolbar
        toolbar = initToolbar();
        FragmentActivity activity = requireActivity();
        if (activity instanceof BaseBindingActivity) {
            ((BaseBindingActivity<?>) activity).setToolbar(toolbar);
        }
        onCreateView();
        return b.getRoot();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        if (handler != null) {
            handler.onDestroy();
            handler = null;
        }
        b = null;
        toolbar = null;
    }

    /**
     * 创建选项菜单
     *
     * @param menu     菜单
     * @param inflater 渲染器
     */
    @Override
    public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
        super.onCreateOptionsMenu(menu, inflater);
        // 强制显示icon
        MenuUtils.showMenuIcon(menu);
    }

    /**
     * 点击选项按钮的操作
     *
     * @param item 选中的按钮
     * @return 是否消耗
     */
    @Override
    public boolean onOptionsItemSelected(@NonNull MenuItem item) {
        return super.onOptionsItemSelected(item);
    }

    /**
     * 当handler存在时，使用它执行 Runnable
     *
     * @param runnable
     */
    public final void ui(Runnable runnable) {
        if (handler == null) {
            return;
        }
        handler.post(runnable);
    }

    /**
     * 当handler存在时，使用它执行 Runnable
     *
     * @param runnable
     * @param delayMillis
     */
    public final void uiDelayed(Runnable runnable, long delayMillis) {
        if (handler == null) {
            return;
        }
        handler.postDelayed(runnable, delayMillis);
    }

    /**
     * 当handler存在时，使用它发送消息
     *
     * @param message
     */
    public final void toast(String message) {
        if (handler == null) {
            return;
        }
        handler.toast(message);
    }

    /**
     * 当handler存在时，使用它发送消息
     *
     * @param message
     */
    public final void toastLong(String message) {
        if (handler == null) {
            return;
        }
        handler.toastLong(message);
    }

    /**
     * 获取当前fragment中的指定位置的子fragment
     *
     * @param position 位置
     * @return Fragment
     */
    public final Fragment getCurrentFragment(int position) {
        return getChildFragmentManager().findFragmentByTag("f" + position);
    }

    /**
     * 暴露handler 给子Fragment获取
     *
     * @return handler
     */
    public MyHandler getHandler() {
        return handler;
    }

    /**
     * 返回父级中的handler
     *
     * @return handler
     */
    @NonNull
    public MyHandler getParentHandler() {
        Fragment parentFragment = getParentFragment();
        if (parentFragment instanceof BaseBindingFragment) {
            return ((BaseBindingFragment<?>) parentFragment).getHandler();
        }
        try {
            FragmentActivity activity = requireActivity();
            if (activity instanceof BaseBindingActivity<?>) {
                return ((BaseBindingActivity<?>) activity).getHandler();
            }
        } catch (IllegalStateException e) {
            Log.w(getClass().getSimpleName(), "IllegalStateException: " + e.getMessage());
        }
        return MyApplication.app.handler;
    }
}
